/* Environment Factory
* Will Seeger
* Desc: Will generate a base world with sky and grass and fences in the world.
* 2/20/2011
*/


#include "StdAfx.h"
#include "EnvironmentFactory.h"
#include "SgObject.h"
#include "SgQuad.h"
#include "SgBox.h"
#include "SgColor.h"
#include "SgComposite.h"
#include "SgMaterial.h"
#include "SgPolygon.h"
#include "SgRegularPolygon.h"
#include "SgRegularCylinder.h"
#include "SgRotateAroundPoint.h"
#include "SgTranslate.h"
#include "SgTransform.h"
#include "SgMesh.h"
#include "SgSphere.h"
#include "graphics/GrVector.h"
#include <cmath>

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

CEnvironmentFactory::CEnvironmentFactory(void)
{
	pavTxt= new CSgTexture(L"pav.bmp");
	grasstex = new CSgTexture(L"Grass.bmp");
	skytex = new CSgTexture(L"sky.bmp");
	orbTex = new CSgTexture(L"messin.bmp");
	marbleTex = new CSgTexture(L"marble.bmp");
}

CEnvironmentFactory::~CEnvironmentFactory(void)
{
}

/*
 * Name: Create()
 * Description: Creates the Environment
 * Parameters: root - the root node of the scene graph to attach to
 */
void CEnvironmentFactory::Create(CSgComposite *root)
{
	m_root = root;
	
	//placing pavement sections
	//
	CSgPtr <CSgComposite> pavement = new CSgComposite();
	CreatePavement(pavement);

	CSgPtr <CSgComposite> pavRow = new CSgComposite();
	CSgPtr <CSgTranslate> pav1 = new CSgTranslate(0.0, 0.0, 0.0);
	pav1->AddChild(pavement);
	CSgPtr <CSgTranslate> pav2 = new CSgTranslate(18, 0, 0);
	pav2->AddChild(pavement);
	CSgPtr <CSgTranslate> pav3 = new CSgTranslate(36, 0, 0);
	pav3->AddChild(pavement);

	pavRow->AddChild(pav1);
	pavRow->AddChild(pav2);
	pavRow->AddChild(pav3);

	CSgPtr <CSgTranslate> pavTrans1 = new CSgTranslate(0.0, 0.0, 6.0);
	pav1->AddChild(pavement);
	
	CSgPtr <CSgTranslate> pavTrans2 = new CSgTranslate(-48, 0, 6);
	pavTrans2->AddChild(pavement);

	CSgPtr <CSgRotateAroundPoint> pav5Rot = new CSgRotateAroundPoint();
	pav5Rot->SetAngle(90);
	pav5Rot->SetPoint(0.0,0.0,0.0);
	pav5Rot->SetNormal(0,1,0);
	
	//pavTrans5->AddChild(pavement);

	CSgPtr <CSgMaterial> pavMat = new CSgMaterial();
	pavMat->SetDiffuseColor(.95f,.95f,.95f,.1f);
	pavMat->SetSpecularColor(.8f,.8f,.8f,.7f);

	
    //going out
	pavTrans1->AddChild(pavRow);
	pavTxt->AddChild(pavTrans1);
	pavTrans2->AddChild(pavRow);
	pavTxt->AddChild(pavTrans2);

	// straight
	CSgPtr <CSgTranslate> pavTrans5 = new CSgTranslate(-6.0, 0, -6.0);
	CSgPtr <CSgTranslate> pavTrans6 = new CSgTranslate(6.0+18*2, 0, -6.0);
	CSgPtr <CSgTranslate> pavTrans7 = new CSgTranslate(6.0+18*4, 0, -6.0);

	CSgPtr <CSgTranslate> pavTrans8 = new CSgTranslate(-6.0, 0, -18*3);
	CSgPtr <CSgTranslate> pavTrans9 = new CSgTranslate(-6.0, 0, -18*5+6);
	
	pav5Rot->AddChild(pavTrans5);
	pav5Rot->AddChild(pavTrans6);
	pav5Rot->AddChild(pavTrans7);
	pavTxt->AddChild(pavTrans8);
	pavTxt->AddChild(pavTrans9);

	pavTrans5->AddChild(pavRow);
	pavTrans6->AddChild(pavRow);
	pavTrans7->AddChild(pavRow);
	pavTrans8->AddChild(pavRow);
	pavTrans9->AddChild(pavRow);

    // final submit to texture and build
	pavMat->AddChild(pavTxt);
	pavTxt->AddChild(pav5Rot);

	m_root->AddChild(pavMat);
	m_root->AddChild(pavTrans1);
	m_root->AddChild(pavTrans2);
	//m_root->AddChild(pav5Rot);


	//Placing the grass land
	//
	CreateGround(grasstex);	
	CSgPtr <CSgTranslate> grass_tran1t = new CSgTranslate(0,0,0);
	CSgPtr <CSgTranslate> grass_tran2t = new CSgTranslate(0,0,(-72)*2);
	grass_tran1t->AddChild(grasstex);
	grass_tran2t->AddChild(grasstex);

	m_root->AddChild(grass_tran1t);
	m_root->AddChild(grass_tran2t);

	//Add the sky with texture mapping
	//
	CreateSky(skytex);	

	CSgPtr <CSgTranslate> sky_tran1t = new CSgTranslate(0,40,0);
	sky_tran1t->AddChild(skytex);
	m_root->AddChild(sky_tran1t);

	//Generates fences
	CSgPtr <CSgComposite> fence = new CSgComposite();
	CreateFence(fence);
    // Perp Fences
	CSgPtr <CSgTranslate> fenceTrans1 = new CSgTranslate(12.0, 0.0, 0);
	fenceTrans1->AddChild(fence);
	CSgPtr <CSgTranslate> fenceTrans2 = new CSgTranslate(24.0, 0.0, 0);
	fenceTrans2->AddChild(fence);
	
	CSgPtr <CSgComposite> fenceRow = new CSgComposite(); // grouping 3 fences in a row
	fenceRow->AddChild(fence);
	fenceRow->AddChild(fenceTrans1);
	fenceRow->AddChild(fenceTrans2);

	CSgPtr <CSgTranslate> fenceTrans3 = new CSgTranslate(36.0, 0.0, 0);
	CSgPtr <CSgTranslate> fenceTrans7 = new CSgTranslate(-42.0, 0.0, 0);
	fenceTrans7->AddChild(fence);
	//CSgPtr <CSgTranslate> fenceTrans8 = new CSgTranslate(-54.0, 0.0, 0);
	//fenceTrans8->AddChild(fence);
	//CSgPtr <CSgTranslate> fenceTrans9 = new CSgTranslate(-66.0, 0.0, 0);
	//fenceTrans9->AddChild(fence);
	CSgPtr <CSgTranslate> fenceTrans10 = new CSgTranslate(-78.0, 0.0, 0);

	//Add Rotated Fences
	CSgPtr <CSgRotateAroundPoint> fenceRot = new CSgRotateAroundPoint();
	fenceRot->SetAngle(-90);
	fenceRot->SetNormal(0,1,0);
	fenceRot->SetPoint(0,0,0);

	CSgPtr <CSgRotateAroundPoint> fenceRot2 = new CSgRotateAroundPoint();
	fenceRot2->SetAngle(-90);
	fenceRot2->SetNormal(0,1,0);
	fenceRot2->SetPoint(0,0,0);
	//drawing X fences
	m_root->AddChild(fenceRow);
	fenceTrans3->AddChild(fenceRow);
	m_root->AddChild(fenceTrans3);
	fenceTrans7->AddChild(fenceRow);
	m_root->AddChild(fenceTrans7);
	fenceTrans10->AddChild(fenceRow);
	m_root->AddChild(fenceTrans10);
	
	//drawing Z fences
	//center row
	CSgPtr <CSgTranslate> fenceTrans11 = new CSgTranslate(-36.0, 0.0, 0.0);
	CSgPtr <CSgTranslate> fenceTrans12 = new CSgTranslate(-36.0,0.0,6.0);
	
	CSgPtr <CSgTranslate> fenceTrans40 = new CSgTranslate(-36.0*1-12  , 0.0, 0.0);
	CSgPtr <CSgTranslate> fenceTrans41 = new CSgTranslate(-36.0*2-6   , 0.0,6.0);
	CSgPtr <CSgTranslate> fenceTrans42 = new CSgTranslate(-36.0*2-12+6, 0.0, 0.0);
	//CSgPtr <CSgTranslate> fenceTrans43 = new CSgTranslate(-36.0*3+6   , 0.0,6.0);
	CSgPtr <CSgTranslate> fenceTrans44 = new CSgTranslate(-36.0*2+6   , 0.0,0.0);
	CSgPtr <CSgTranslate> fenceTrans45 = new CSgTranslate(-36.0*3-12, 0.0,6.0);
	CSgPtr <CSgTranslate> fenceTrans46 = new CSgTranslate(-36.0*4+6+12+6   , 0.0,0.0);
	
	fenceRot->AddChild(fenceTrans11);
	fenceRot->AddChild(fenceTrans12);
	fenceTrans11->AddChild(fenceRow);
	fenceTrans12->AddChild(fenceRow);

	fenceRot2->AddChild(fenceTrans40);//r
	fenceRot2->AddChild(fenceTrans41);//l
	fenceRot2->AddChild(fenceTrans42);//r
	//fenceRot2->AddChild(fenceTrans43);//l
	fenceRot2->AddChild(fenceTrans44);//r
	fenceRot2->AddChild(fenceTrans45);//l
	fenceRot2->AddChild(fenceTrans46);//r
	fenceTrans40->AddChild(fence);
	fenceTrans41->AddChild(fenceRow);
	fenceTrans42->AddChild(fence);
	//fenceTrans43->AddChild(fence);
	fenceTrans44->AddChild(fence);
	fenceTrans45->AddChild(fenceRow);
	fenceTrans46->AddChild(fenceRow);

	CSgPtr <CSgTranslate> fenceTrans13 = new CSgTranslate(-36.0, 0.0, 72.0);
	CSgPtr <CSgTranslate> fenceTrans14 = new CSgTranslate(-36.0*2, 0.0, 72.0);
	CSgPtr <CSgTranslate> fenceTrans15 = new CSgTranslate(-36.0*3, 0.0, 72.0);
	CSgPtr <CSgTranslate> fenceTrans16 = new CSgTranslate(-36.0*4, 0.0, 72.0);
	CSgPtr <CSgTranslate> fenceTrans17 = new CSgTranslate(-36.0*5, 0.0, 72.0);
	CSgPtr <CSgTranslate> fenceTrans18 = new CSgTranslate(-36.0*6, 0.0, 72.0);

	CSgPtr <CSgTranslate> fenceTrans21 = new CSgTranslate(  -36.0, 0.0, -72.0);
	CSgPtr <CSgTranslate> fenceTrans22 = new CSgTranslate(-36.0*2, 0.0, -72.0);
	CSgPtr <CSgTranslate> fenceTrans23 = new CSgTranslate(-36.0*3, 0.0, -72.0);
	CSgPtr <CSgTranslate> fenceTrans24 = new CSgTranslate(-36.0*4, 0.0, -72.0);
	CSgPtr <CSgTranslate> fenceTrans25 = new CSgTranslate(-36.0*5, 0.0, -72.0);
	CSgPtr <CSgTranslate> fenceTrans26 = new CSgTranslate(-36.0*6, 0.0, -72.0);
	 
	//left wall
	fenceRot->AddChild(fenceTrans13);
	fenceRot->AddChild(fenceTrans14);
	fenceRot->AddChild(fenceTrans15);
	fenceRot->AddChild(fenceTrans16);
	fenceRot->AddChild(fenceTrans17);
	fenceRot->AddChild(fenceTrans18);
	fenceTrans13->AddChild(fenceRow);
	fenceTrans14->AddChild(fenceRow);
	fenceTrans15->AddChild(fenceRow);
	fenceTrans16->AddChild(fenceRow);
	fenceTrans17->AddChild(fenceRow);
	fenceTrans18->AddChild(fenceRow);

	//right wall
	fenceRot->AddChild(fenceTrans21);
	fenceRot->AddChild(fenceTrans22);
	fenceRot->AddChild(fenceTrans23);
	fenceRot->AddChild(fenceTrans24);
	fenceRot->AddChild(fenceTrans25);
	fenceRot->AddChild(fenceTrans26);
	fenceTrans21->AddChild(fenceRow);
	fenceTrans22->AddChild(fenceRow);
	fenceTrans23->AddChild(fenceRow);
	fenceTrans24->AddChild(fenceRow);
	fenceTrans25->AddChild(fenceRow);
	fenceTrans26->AddChild(fenceRow);

	//back wall
	CSgPtr <CSgTranslate> fenceTrans30 = new CSgTranslate(-72     , 0.0, -72.0*3);
	CSgPtr <CSgTranslate> fenceTrans31 = new CSgTranslate(-72+36  , 0.0, -72.0*3);
	CSgPtr <CSgTranslate> fenceTrans32 = new CSgTranslate(-72+36*2, 0.0, -72.0*3);
	CSgPtr <CSgTranslate> fenceTrans33 = new CSgTranslate(-72+36*3, 0.0, -72.0*3);

	fenceTrans30->AddChild(fenceRow);
	fenceTrans31->AddChild(fenceRow);
	fenceTrans32->AddChild(fenceRow);
	fenceTrans33->AddChild(fenceRow);

	m_root->AddChild(fenceTrans30);
	m_root->AddChild(fenceTrans31);
	m_root->AddChild(fenceTrans32);
	m_root->AddChild(fenceTrans33);

	// seperators F
	CSgPtr <CSgTranslate> fenceTrans50 = new CSgTranslate(-72      , 0.0, -72.0);
	CSgPtr <CSgTranslate> fenceTrans51 = new CSgTranslate(-72+36   , 0.0, -72.0);
	CSgPtr <CSgTranslate> fenceTrans52 = new CSgTranslate(-72+36+12, 0.0, -72.0);
	CSgPtr <CSgTranslate> fenceTrans53 = new CSgTranslate(-72+36+12+6, 0.0, -72.0);
	CSgPtr <CSgTranslate> fenceTrans54 = new CSgTranslate(-72+36*2   , 0.0, -72.0);
	CSgPtr <CSgTranslate> fenceTrans55 = new CSgTranslate(-72+36*3   , 0.0, -72.0);

	fenceTrans50->AddChild(fenceRow);
	fenceTrans51->AddChild(fence);
	fenceTrans52->AddChild(fence);
	fenceTrans53->AddChild(fence);
	fenceTrans54->AddChild(fenceRow);
	fenceTrans55->AddChild(fenceRow);

	m_root->AddChild(fenceTrans50);
	m_root->AddChild(fenceTrans51);
	m_root->AddChild(fenceTrans52);
	m_root->AddChild(fenceTrans53);
	m_root->AddChild(fenceTrans54);
	m_root->AddChild(fenceTrans55);

	// seperators B
	CSgPtr <CSgTranslate> fenceTrans60 = new CSgTranslate(-72      , 0.0, -120);
	CSgPtr <CSgTranslate> fenceTrans61 = new CSgTranslate(-72+36   , 0.0, -120);
	CSgPtr <CSgTranslate> fenceTrans62 = new CSgTranslate(-72+36+12, 0.0, -120);
	CSgPtr <CSgTranslate> fenceTrans63 = new CSgTranslate(-72+36+12+6, 0.0, -120);
	CSgPtr <CSgTranslate> fenceTrans64 = new CSgTranslate(-72+36*2   , 0.0, -120);
	CSgPtr <CSgTranslate> fenceTrans65 = new CSgTranslate(-72+36*3   , 0.0, -120);

	fenceTrans60->AddChild(fenceRow);
	fenceTrans61->AddChild(fence);
	fenceTrans62->AddChild(fence);
	fenceTrans63->AddChild(fence);
	fenceTrans64->AddChild(fenceRow);
	fenceTrans65->AddChild(fenceRow);

	m_root->AddChild(fenceTrans60);
	m_root->AddChild(fenceTrans61);
	m_root->AddChild(fenceTrans62);
	m_root->AddChild(fenceTrans63);
	m_root->AddChild(fenceTrans64);
	m_root->AddChild(fenceTrans65);

	// final fence generation

	
	
	m_root->AddChild(fenceRot);
	m_root->AddChild(fenceRot2);



	// Create all the signs
	CreateBanner(m_root, L"welcome.bmp");

	CSgPtr<CSgTranslate> roundUpSignMov = new CSgTranslate(-6, 0, -92+6+2);
	CSgPtr<CSgRotateAroundPoint> roundUpSignRot = new CSgRotateAroundPoint();
	roundUpSignRot->SetAngle(90);
	roundUpSignRot->SetNormal(0, 1, 0);
	roundUpSignRot->SetPoint(0, 0, 0);
	m_root->AddChild(roundUpSignMov);
	roundUpSignMov->AddChild(roundUpSignRot);
	CreateBanner(roundUpSignRot, L"signRoundUp.bmp");


	CSgPtr<CSgTranslate> scramSignMov = new CSgTranslate(-6, 0, -42);
	CSgPtr<CSgRotateAroundPoint> scramSignRot = new CSgRotateAroundPoint();
	scramSignRot->SetAngle(90);
	scramSignRot->SetNormal(0, 1, 0);
	scramSignRot->SetPoint(0, 0, 0);
	m_root->AddChild(scramSignMov);
	scramSignMov->AddChild(scramSignRot);
	CreateBanner(scramSignRot, L"signScrambledEggs.bmp");


	CSgPtr<CSgTranslate> goKartSignMov = new CSgTranslate(0, 0, -48);
	CSgPtr<CSgRotateAroundPoint> goKartSignRot = new CSgRotateAroundPoint();
	goKartSignRot->SetAngle(-90);
	goKartSignRot->SetNormal(0, 1, 0);
	goKartSignRot->SetPoint(0, 0, 0);
	m_root->AddChild(goKartSignMov);
	goKartSignMov->AddChild(goKartSignRot);
	CreateBanner(goKartSignRot, L"signGoKarts.bmp");



	CSgPtr<CSgTranslate> goRoundSignMov = new CSgTranslate(0, 0, -78);
	CSgPtr<CSgRotateAroundPoint> goRoundSignRot = new CSgRotateAroundPoint();
	goRoundSignRot->SetAngle(-90);
	goRoundSignRot->SetNormal(0, 1, 0);
	goRoundSignRot->SetPoint(0, 0, 0);
	m_root->AddChild(goRoundSignMov);
	goRoundSignMov->AddChild(goRoundSignRot);
	CreateBanner(goRoundSignRot, L"signMerryGoRound.bmp");


	
	CSgPtr<CSgTranslate> pirateShipSignMov = new CSgTranslate(0, 0, -114);
	CSgPtr<CSgRotateAroundPoint> pirateShipSignRot = new CSgRotateAroundPoint();
	pirateShipSignRot->SetAngle(0);
	pirateShipSignRot->SetNormal(0, 1, 0);
	pirateShipSignRot->SetPoint(0, 0, 0);
	m_root->AddChild(pirateShipSignMov);
	pirateShipSignMov->AddChild(pirateShipSignRot);
	CreateBanner(pirateShipSignRot, L"signPirateShip.bmp");

	// Adding fountain 
	CSgPtr<CSgComposite> fountain = new CSgComposite();
	CreateFountain(fountain);
	CSgPtr<CSgTranslate> fountainTrans = new CSgTranslate(-3, 0, 24);
	fountainTrans->AddChild(fountain);
	m_root->AddChild(fountainTrans);
}

/*
 * Name: CreateFloor()
 * Description: Creates the Grass
 * Parameters: root - the root node of the scene graph to attach to
 */
void CEnvironmentFactory::CreateFloor(CSgComposite *parent)
{ //originally used to create grass
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //Yang Test
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //Yang Test

	CSgPtr <CSgPolygon> floor = new CSgPolygon();
	CGrVector v1(0,0,0);
	CGrVector v2(0,0,18);
	CGrVector v3(18,0,18);
	CGrVector v4(18,0,0);

	CGrVector v3C(1,0,6);
	CGrVector v4C(1,0,0);
	floor->AddVertices(v1,v2,v3,v4);
	CGrVector n(0,1,0);
	floor->AddNormal(n);
	floor->AddTexCoord(n);

	/*CSgRotateAroundPoint *floorRotate = new CSgRotateAroundPoint();
	floorRotate->SetAngle(180);
	floorRotate->SetNormal(CGrVector(1, 0, 0));
	floorRotate->SetPoint(CGrVector(0, 0, 0));
	floorRotate->AddChild(floor);*/

	CSgPtr <CSgTranslate> floorTrans2 = new CSgTranslate(18, 0, 0);
	floorTrans2->AddChild(floor);
	CSgPtr <CSgTranslate> floorTrans3 = new CSgTranslate(18, 0, 18);
	floorTrans3->AddChild(floor);
	CSgPtr <CSgTranslate> floorTrans4 = new CSgTranslate(0, 0, 18);
	floorTrans4->AddChild(floor);
	
	//floorTrans->AddChild(floorRotate);

	CSgPtr <CSgMaterial> green = new CSgMaterial();
	green->SetDiffuseColor(0.f, .35f, .03f, 1.f);
	green->SetSpecularColor(0.f, .35f, .03f, 1.f);
	green->AddChild(floor);
	green->AddChild(floorTrans2);
	green->AddChild(floorTrans3);
	green->AddChild(floorTrans4);

	parent->AddChild(green);

	/*parent->AddChild(floor);
	parent->AddChild(floorTrans2);
	parent->AddChild(floorTrans3);
	parent->AddChild(floorTrans4);*/
}

/*
 * Name: CreatePavement()
 * Description: Creates the pavement sections
 * Parameters: parent, the node which to add this
 */
void CEnvironmentFactory::CreatePavement(CSgComposite *parent)
{
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //Yang Test
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //Yang Test
	CSgPtr <CSgPolygon> pavement = new CSgPolygon();

	CGrVector v1(0,0,0);
	CGrVector v2(0,0,5.9);
	CGrVector v3(5.9,0,5.9);
	CGrVector v4(5.9,0,0);

	CGrVector v3C(5.9,0,5.9);
	CGrVector v4C(5.9,0,0);
	CGrVector vT(0,1,0);

	pavement->AddVertices(v1,v2,v3C,v4C);
	pavement->AddTexCoord(CGrVector(0,0));
	pavement->AddTexCoord(CGrVector(0,1));
	pavement->AddTexCoord(CGrVector(1,1));
	pavement->AddTexCoord(CGrVector(1,0));
	CGrVector n(0,1,0);
	pavement->AddNormal(n);
	
	CSgPtr <CSgTranslate> PavTrans = new CSgTranslate(.05, .1, .05);
	PavTrans->AddChild(pavement);
	CSgPtr <CSgTranslate> PavTrans2 = new CSgTranslate(6.05, .1, .05);
	PavTrans2->AddChild(pavement);
	CSgPtr <CSgTranslate> PavTrans3 = new CSgTranslate(12.05, .1, .05);
	PavTrans3->AddChild(pavement);

	CSgPtr <CSgMaterial> gray = new CSgMaterial();
	gray->SetDiffuseColor(.51f, .52f, .48f, 1.f);
	gray->SetSpecularColor(.51f, .52f, .48f, 1.f);


	gray->AddChild(PavTrans);
	gray->AddChild(PavTrans2);
	gray->AddChild(PavTrans3);

	parent->AddChild(gray);
}

/*
 * Name: CreateFence()
 * Description: Creates the fence sections
 * Parameters: parent, the node which to add this
 */
void CEnvironmentFactory::CreateFence(CSgComposite *parent)
{
	CSgPtr <CSgRegularCylinder> fencePost = new CSgRegularCylinder();
	fencePost->SetProperties(4,2,.3);

	CSgPtr <CSgComposite> board = new CSgComposite();
	CSgPtr <CSgPolygon> board1 = new CSgPolygon();
	CSgPtr <CSgPolygon> board2 = new CSgPolygon();
	CSgPtr <CSgPolygon> board3 = new CSgPolygon();
	CSgPtr <CSgPolygon> board4 = new CSgPolygon();
	CSgPtr <CSgPolygon> board5 = new CSgPolygon();
	CSgPtr <CSgPolygon> board6 = new CSgPolygon();
	board->AddChild(board1);
	board->AddChild(board2);
	board->AddChild(board3);
	board->AddChild(board4);
	board->AddChild(board5);
	board->AddChild(board6);

	GLdouble a[] = {0.0, 0, .2};
    GLdouble b[] = {12., 0, .2};
    GLdouble c[] = {12., .35, .2};
    GLdouble d[] = {0.0, .35, .2};
    GLdouble e[] = {0.0, .35, -0.2};
	GLdouble f[] = {12., .35, -.2};
	GLdouble g[] = {12., 0, -.2};
	GLdouble h[] = {0.0, 0, -0.2};
	
	board1->AddVertices(a,b,c,d); //Front 
	board1->AddNormal( CGrVector(0.0, 0.0, 1.0));
	/*board->AddNormal(n);
	board->AddNormal(n);
	board->AddNormal(n);*/
	board2->AddVertices( c,b,g,f); //Right
	board2->AddNormal( CGrVector(1.0, 0.0, 0.0));
	board3->AddVertices( e,f,g,h); //Back
	board3->AddNormal( CGrVector(0.0, 0.0, -1.0));
	board4->AddVertices( d,e,h,a); //Left
	board4->AddNormal(CGrVector(-1.0, 0.0, 0.0));
	board5->AddVertices(d,c,f,e); //Top
	board5->AddNormal( CGrVector(0.0, 1.0, 0.0));
	board6->AddVertices(h,g,b,a); //Bottom
	board6->AddNormal(CGrVector(0.0, -1.0, 0.0));

	CSgPtr <CSgTranslate> FenceTrans = new CSgTranslate(0.0, 0.0, 0.0);
	FenceTrans->AddChild(fencePost);
	CSgPtr <CSgTranslate> FenceTrans2 = new CSgTranslate(12.0, 0.0, 0.0);
	FenceTrans2->AddChild(fencePost);
	CSgPtr <CSgTranslate> boardTrans1 = new CSgTranslate(0.0, 1.5, 0.0);
	boardTrans1->AddChild(board);
	CSgPtr <CSgTranslate> boardTrans2 = new CSgTranslate(0.0, 1.0, 0.0);
	boardTrans2->AddChild(board);
	CSgPtr <CSgTranslate> boardTrans3 = new CSgTranslate(0.0, .5, 0.0);
	boardTrans3->AddChild(board);

	CSgPtr <CSgMaterial> brown = new CSgMaterial();
	brown->SetDiffuseColor(.51f, .36f, .25f, 1.f);
	brown->SetSpecularColor(.51f, .36f, .25f, 1.f);

	parent->AddChild(brown);

	brown->AddChild(FenceTrans);
	brown->AddChild(FenceTrans2);
	brown->AddChild(boardTrans1);
	brown->AddChild(boardTrans2);
	brown->AddChild(boardTrans3);

}

void CEnvironmentFactory::CreateSky(CSgComposite* parent)
{
	CSgPtr <CSgPolygon> test = new CSgPolygon();
	test->AddVertex3d(172, 0, -172);
	test->AddTexCoord(CGrVector(0,0));
	test->AddVertex3d(172, 0, 172);
	test->AddTexCoord(CGrVector(0,1));
	test->AddVertex3d(-172, 0, 172);
	test->AddTexCoord(CGrVector(1,1));
	test->AddVertex3d(-172, 0, -172);
	test->AddTexCoord(CGrVector(1,0));


	test->AddNormal(CGrVector(0,-1,0));
	CSgPtr <CSgMaterial> green = new CSgMaterial();
	parent->AddChild(green);
	green->AddChild(test);
	//parent->AddChild(test);
}
void CEnvironmentFactory::CreateGround(CSgComposite* parent)
{
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //Yang Test
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //Yang Test
	CSgPtr <CSgPolygon> ground = new CSgPolygon();
	ground->AddVertex3d(-72, 0, -172);
	ground->AddTexCoord(CGrVector(72,0));
	ground->AddVertex3d(-72, 0, 72);
	ground->AddTexCoord(CGrVector(72,72));
	ground->AddVertex3d(72, 0, 72);
	ground->AddTexCoord(CGrVector(0,72));
	ground->AddVertex3d(72, 0, -172);
	ground->AddTexCoord(CGrVector(0,0));
	ground->AddNormal(CGrVector(0,1,0));
	
	CSgPtr <CSgMaterial> green = new CSgMaterial();
	green->SetDiffuseColor(0.f, .35f, .03f, 1.f);
	green->SetSpecularColor(0.f, .35f, .03f, 1.f);
	parent->AddChild(green);
	green->AddChild(ground);
}



void CEnvironmentFactory::CreateBanner(CSgComposite *parent, LPCTSTR filename)
{
	// Create the banner poles
	CSgPtr <CSgRegularCylinder> bannerPole = new CSgRegularCylinder();
	bannerPole->SetProperties(30, 6, .2);
	CSgPtr <CSgTranslate> bannerPoleMov1 = new CSgTranslate(0, 2, 0);
	bannerPoleMov1->AddChild(bannerPole);
	CSgPtr <CSgTranslate> bannerPoleMov2 = new CSgTranslate(-6, 2, 0);
	bannerPoleMov2->AddChild(bannerPole);

	CSgPtr <CSgMaterial> poleColor = new CSgMaterial();
	poleColor->SetDiffuseColor(.531f ,.531f ,.531f ,1.f);
	poleColor->SetSpecularColor(.531f ,.531f ,.531f ,1.f);
	poleColor->AddChild(bannerPoleMov1);
	poleColor->AddChild(bannerPoleMov2);
	parent->AddChild(poleColor);


	CSgPtr<CSgTexture> welcome = new CSgTexture(filename);


	CSgPtr <CSgMesh> banner = new CSgMesh();
	//banner->SetTexture(welcome);
	welcome->AddChild(banner);

	// loop y =  cos(x * 6/(4pi))
	for(double xVal = 0; xVal <= 6; xVal += 0.1)
	{
		banner->AddVertex(CGrVector(xVal, sin(2.4 * xVal)/4 + .5, .05));
		banner->AddTexCoord(CGrVector(xVal / 12.0, 1, 0));
	}
	for(double xVal = 0; xVal <= 6; xVal += 0.1)
	{
		banner->AddVertex(CGrVector(xVal, sin(2.4 * xVal)/4 - 1, .05));
		banner->AddTexCoord(CGrVector(xVal / 12.0, 0, 0));
	}
	for(double xVal = 0; xVal <= 6; xVal += 0.1)
	{
		banner->AddVertex(CGrVector(xVal, sin(2.4 * xVal)/4 + .5, -.05));
		banner->AddTexCoord(CGrVector(1.05 - xVal / 12.0, 1, 0));
	}
	for(double xVal = 0; xVal <= 6; xVal += 0.1)
	{
		banner->AddVertex(CGrVector(xVal, sin(2.4 * xVal)/4 - 1, -.05));
		banner->AddTexCoord(CGrVector(1.05 - xVal / 12.0, 0, 0));
	}

	banner->AddNormal(CGrVector(0, 0, 1));
	banner->AddNormal(CGrVector(0, 0, -1));
	banner->AddNormal(CGrVector(0, 1, 0));
	banner->AddNormal(CGrVector(0, -1, 0));

	for(int i=0; i < 60; i++)
		banner->AddFlatQuad(i+1, i, i+61, i+62, 0, 1);

	for(int i=122; i < 180; i++)
		banner->AddFlatQuad(i, i+1, i+62, i+61, 1, 1);
	
	for(int i=1; i<60; i++)
		banner->AddFlatQuad(i, i+1, i+122, i+121, 2, 1);
		
	for(int i=62; i<119; i++)
		banner->AddFlatQuad(i+1, i, i+121, i+122, 3, 1);



	//		bannerBack->AddFlatQuad(i, i+1, i+62, i+61, 0);
	CSgPtr <CSgTranslate> bannerMov = new CSgTranslate(-6, 7, 0);
	parent->AddChild(bannerMov);
	bannerMov->AddChild(welcome);
}

void CEnvironmentFactory::CreateFountain(CSgComposite* parent)
{	
	CSgPtr <CSgSphere> orb = new CSgSphere(3);

	CSgPtr <CSgRegularCylinder> botPiece = new CSgRegularCylinder();
	botPiece->SetProperties(15, 6, 1);
	
	CSgPtr <CSgRegularCylinder> conn = new CSgRegularCylinder();
	conn->SetProperties(15, 1.5, 3);

	CSgPtr <CSgTranslate> orbTrans = new CSgTranslate(0, 6, 0);
	orbTrans->AddChild(orb);
	CSgPtr <CSgTranslate> connTrans = new CSgTranslate(0, 0, 0);
	connTrans->AddChild(conn);

	CSgPtr <CSgMaterial> granite = new CSgMaterial();
	granite->SetDiffuseColor(.67f ,.67f ,.67f ,1.f);
	granite->SetSpecularColor(.67f ,.67f ,.67f ,1.f);
	
	marbleTex->AddChild(connTrans);
	marbleTex->AddChild(botPiece);
	orbTex->AddChild(orbTrans);
	
	granite->AddChild(orbTex);
	granite->AddChild(marbleTex);
	
	parent->AddChild(granite);

}